using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using PlainConcepts.Fx.Dnie.DigitalSign.Configuration;
using System.Reflection;

namespace PlainConcepts.Fx.Dnie.DigitalSign
{
	/// <summary>
	/// Loader of plugins to digital sign documents
	/// </summary>
	static class SignerLoader
	{
		#region Static Members

		static readonly Dictionary<string, DigitalSignerElement> pluginsCollection = new Dictionary<string, DigitalSignerElement>();

		#endregion

		#region Static Constructor

	    static SignerLoader()
		{
			try
			{
				System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
				if (config != null)
				{
					DigitalSignerSection digitalSignerSection = config.GetSection("DniE") as DigitalSignerSection;
					if (digitalSignerSection != null)
					{
						DigitalSignerElementCollection plugins = digitalSignerSection.Plugins;
						foreach (DigitalSignerElement plugin in plugins)
						{
							pluginsCollection.Add(plugin.DocumentExtension, plugin);
						}
					}
				}
			}
			catch (ConfigurationException)
			{
				//TODO:Poner aqui
			}
		}

		#endregion

		#region Static Public Methods

		public static IDigitalSigner GetPlugin(string extension)
		{
            if (pluginsCollection.ContainsKey(extension))
            {
                try
                {
                    string type = pluginsCollection[extension].PluginType.Split(',')[0].Trim();
                    string assembly = pluginsCollection[extension].PluginType.Split(',')[1].Trim();

                    Assembly pluginAssembly = Assembly.Load(assembly);
                    Type pluginType = pluginAssembly.GetType(type);
                    if (typeof(IDigitalSigner).IsAssignableFrom(pluginType))
                    {
                        return (IDigitalSigner)Activator.CreateInstance(pluginType);
                    }
                    else
                    {
                        //Invalid plugin type
                        throw new ConfigurationErrorsException(Resources.Messages.exception_DigitalSign_SignerLoader_InvalidTypeName);
                    }
                }
                catch (IndexOutOfRangeException)
                {
                    //PluginType mal formado
                    throw new ConfigurationErrorsException(Resources.Messages.exception_DigitalSign_SignerLoader_InvalidTypeName);
                }
            }
            else
            {
                //Extension not present in configuration
                throw new ArgumentException(string.Format(Resources.Messages.exception_DigitalSign_Configuration_SignerLoader_NoPluginForExtension, extension));
            }

		}
		#endregion
	}
}
